using System.Windows.Forms;
using NUnit.Framework;
using ShadeTree.Binding.Elements;

namespace ShadeTree.Binding.Tests
{
    [TestFixture]
    public class When_binding_a_BoundScreenElement
    {
        #region Setup/Teardown

        [SetUp]
        public void SetUp()
        {
            _target = new BindingTarget();
            _control = new Control();
            _element = new StubbedBoundScreenElement(SingleProperty.Build<BindingTarget>(x => x.Name), _control);
        }

        #endregion

        private BindingTarget _target;
        private Control _control;
        private StubbedBoundScreenElement _element;

        [Test]
        public void ApplyChanges_sets_the_property_to_the_value_of_the_control()
        {
            _target.Name = "Jeremy D. Miller";
            _element.Bind(_target);
            _control.Text.ShouldEqual(_target.Name);

            _control.Text = "something different";
            _element.ApplyChanges();
            _target.Name.ShouldEqual("something different");
        }

        [Test]
        public void Calling_Reset_Sets_The_Property_And_Control_Value_Back_To_The_Original_Values()
        {
            _target.Name = "Jeremy D. Miller";
            _element.Bind(_target);
            _target.Name = "Julia L. Miller";
            _element.Update();

            _element.Reset();

            _target.Name.ShouldEqual("Jeremy D. Miller");
            _control.Text.ShouldEqual("Jeremy D. Miller");
        }

        [Test]
        public void Set_The_control_value_from_the_target_on_Bind()
        {
            _control.Text = "nothing";
            _target.Name = "Jeremy D. Miller";
            _element.Bind(_target);
            _control.Text.ShouldEqual(_target.Name);
        }

        [Test]
        public void Update_sets_the_control_to_the_value_of_the_bound_property()
        {
            _target.Name = "Jeremy D. Miller";
            _element.Bind(_target);
            _control.Text.ShouldEqual(_target.Name);

            _target.Name = "Julia L. Miller";
            _element.Update();
            _control.Text.ShouldEqual("Julia L. Miller");
        }
    }

    public class BindingTarget
    {
        public string Name { get; set; }
    }

    public class StubbedBoundScreenElement : BoundScreenElement<Control, string>
    {
        private readonly Control _control;

        public StubbedBoundScreenElement(Accessor property, Control control) : base(property, control)
        {
            _control = control;
        }

        protected override string getValueFromControl()
        {
            return _control.Text;
        }

        protected override void resetControl(string originalValue)
        {
            _control.Text = originalValue;
        }


        protected override void tearDown()
        {
        }
    }
}